/**
 * 着色器常用方法
 */

let ShaderMethod= {
    prjVec_v3_a_v3_b: [
        'vec3 prjVec(vec3 a,vec3 b){' ,
        '   float scl=dot(b,a)/(b.x*b.x+b.y*b.y+b.z*b.z);' ,
        '   return b*scl;' ,
        '}'
    ].join('\n'),
    prjPlane_v3_a_v3_planeNormal: [
        'vec3 prjPlane(vec3 a,vec3 plane){' ,
        '   vec3 p=projectOnVec(a,plane);' ,
        '   return a-p;' ,
        '}'
    ].join('\n'),
    getAspect: [
        'float getAspect(){' ,
        '   float a=projectionMatrix[0][0];' ,
        '   float b=projectionMatrix[1][1];' ,
        '   return abs(b/a);',
        '}'
    ].join('\n'),
    computeAspect: [
        'float computeAspect(){' ,
        '   float aspect=0.5625;' ,
        '   if(projectionMatrix[3][3]==0.0){' ,
        '      float _tan=projectionMatrix[1][1];' ,
        '      float as_tan=1.0/projectionMatrix[0][0];' ,
        '      aspect=1.0/(as_tan*_tan);' ,
        '   }else{' ,
        '      float _height=1.0/projectionMatrix[1][1];' ,
        '      float _width=1.0/projectionMatrix[0][0];' ,
        '      aspect=_height/_width;' ,
        '   }' ,
        '   return aspect;' ,
        '}'
    ].join('\n'),
    angleOfVec_v3_a_v3_b: [
        'float angleOfVec(vec3 a,vec3 b){',
        '   float d=dot(a,b);',
        '   float sa=a.x*a.x+a.y*a.y+a.z*a.z;',
        '   float sb=b.x*b.x+b.y*b.y+b.z*b.z;',
        '   float theta=d/sqrt(sa*sb);',
        '   return acos(clamp(theta,-1.0,1.0));',
        '}'
    ].join('\n'),
    checkPerspective: [
        'bool checkPerspective(){' ,
        '   return projectionMatrix[3][3]==0.0;' ,
        '}',
    ].join('\n'),
    getNear: [
        'float getNear(){' ,
        '   float near=0.0;' ,
        '   if(projectionMatrix[3][3]==0.0){',
        '      float e33=projectionMatrix[2][2];',
        '      float e43=projectionMatrix[3][2];',
        '      near=e43/(e33-1.0);',
        '   }else{',
        '      float e33=projectionMatrix[2][2];',
        '      float e43=projectionMatrix[3][2];',
        '      near=(e43+1.0)/e33;',
        '   }' ,
        '   return near;' ,
        '}',
    ].join('\n'),
    getFar: [
        'float getFar(){' ,
        '   float far=10.0;' ,
        '   if(projectionMatrix[3][3]==0.0){',
        '      float e33=projectionMatrix[2][2];',
        '      float e43=projectionMatrix[3][2];',
        '      far=e43/(1.0+e33);',
        '   }else{',
        '      float e33=projectionMatrix[2][2];',
        '      float e43=projectionMatrix[3][2];',
        '      far=(e43-1.0)/e33;',
        '   }' ,
        '   return far;' ,
        '}',
    ].join('\n'),
    getDistribution_float_x_float_sigma: [
        'float getDistribution(float x,float sigma){',
        '   float sigmaP=1.0/sigma;',
        '   float dP=disP*sigmaP;',
        '   float xp=-0.5*sigma;',
        '   float pe=pow(e,xp*x*x);',
        '   return dP*pe;',
        '}'
    ].join('\n'),
    zoneEqual_float_a_float_b_float_range: [
        'bool zoneEqual(float a,float b,float range){',
        '   bool _a=(a< b+range&&a>b-range);',
        '   bool _b=(b< a+range&&b>a-range);',
        '   return _a&&_b;',
        '}'
    ].join('\n'),
    attenuateByCos_float_length_float_val: [
        'float attenuateByCos(float length,float val){',
        '   float a=1.5708/length*val;',
        '   return cos(a);',
        '}'
    ].join('\n'),
    random_vec2_uv_float_offset: [
        'float random( vec2 uv,float offset ) {',
        '   float a = 12.9898, b = 78.233, c = 43758.5453;',
        '   float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, 3.1415926 );',
        '   return fract(sin(sn) * c*offset);',
        '}'
    ].join('\n'),
    hash_float_f: [
        'float hash(float f){',
        '   return fract( sin(f * 77321.81283) );',
        '}'
    ].join('\n'),
    sub_float_d_float_d2: [
        'float sub( float d, float d2 ){',
        '   return max(-d2, d);',
        '}',
    ].join('\n'),
    add_float_d2_float_d: [
        'float add( float d2, float d ){',
        '   return min(d2, d);',
        '}',
    ].join('\n'),
    sect_float_d_float_d2: [
        'float sect( float d, float d2 ){',
        '   return max(d,d2);',
        '}',
    ].join('\n'),
    rotate_float_ang_vec2_v: [
        'vec2 rotate( float ang, vec2 v ){',
        '   float s = sin(ang);',
        '   float c = cos(ang);',
        '   return vec2( c*v.x-s*v.y, s*v.x+c*v.y );',
        '}',
    ].join('\n'),
    circle_vec2_where_vec2_uv_float_radius: [
        'float circle( vec2 where, vec2 uv, float radius ){',
        '   vec2 dv = uv-where;',
        '   return sqrt(dot(dv,dv))-radius;',
        '}',
    ].join('\n'),
    ellips_vec2_where_vec2_uv_vec2_ab_float_radius: [
        'float ellips( vec2 where, vec2 uv, vec2 ab, float radius ){',
        '   vec2 dv = (uv-where) / ab;',
        '   return length(dv)-radius;',
        '}',
    ].join('\n'),
    square_vec2_where_vec2_uv_vec2_hsize: [
        'float square( vec2 where, vec2 uv, vec2 hsize ){',
        '   vec2 dv = abs(uv - where) - hsize;',
        '   return min(0., max(dv.x, dv.y)) + length(max(dv,0.));',
        '}',
    ].join('\n'),
    nsmoothstep_float_e0_float_e1_float_x_float_f: [
        'float nsmoothstep(float e0, float e1, float x, float f){',
        '   f=1./f;',
        '   x = smoothstep(e0*f,e1*f,x);',
        '   return x;',
        '}',
    ].join('\n'),
    strokestep_float_e_float_m_float_x_vec3_left_vec3_mid_vec3_right: [
        'vec3 strokestep( float e, float m, float x, vec3 left, vec3 mid, vec3 right ){',
        '   return mix( mix( left, mid, smoothstep( -e-m, -m, x ) ), right,smoothstep( m, e+m, x ) );',
        '}',
    ].join('\n'),
    line_vec2_uv_vec2_a_vec2_b_need_rotate_method: [
        'float line( vec2 uv, vec2 a, vec2 b ){',
        '   vec2 d=a-b;',
        '   vec2 m=(a+b)*0.5;',
        '   vec2 luv=rotate(-atan(d.y,d.x), uv-m);',
        '   vec2 cp=luv;',
        '   float len=length(d);',
        '   cp.y=0.;',
        '   cp.x = max(min(luv.x,len*0.5), -len*.5);',
        '   return distance(cp,luv);',
        '}',
    ].join('\n'),
    trapezoid_vec2_uv_vec3_s_float_edge_need_line_add_method: [
        'float trapezoid( vec2 uv, vec3 s, float edge ){',
        '   vec2 cp0 = vec2(-s.x,s.z)*.5;',
        '   vec2 cp1 = cp0+vec2(s.x,0.);',
        '   vec2 cp2 = vec2(-s.y,-s.z)*.5;',
        '   vec2 cp3 = cp2+vec2(s.y,0.);',
        '   float d = line( uv, cp0, cp1 );',
        '   d = add( d, line( uv, cp1, cp3 ) );',
        '   d = add( d, line( uv, cp3, cp2 ) );',
        '   d = add( d, line( uv, cp2, cp0 ) );',
        '   return d-edge;',
        '}',
    ].join('\n'),
    triangle_vec2_uv_vec2_p1_vec2_p2_vec2_p3: [
        'float triangle(vec2 uv,vec2 p1,vec2 p2,vec2 p3){',
        '   vec2 v0 = p3-p1;',
        '   vec2 v1 = p2-p1;',
        '   vec2 v2 = uv-p1;',
        '   float d00, d01, d02, d11, d12;',
        '   d00 = dot(v0,v0);',
        '   d01 = dot(v1,v0);',
        '   d02 = dot(v2,v0);',
        '   d11 = dot(v1,v1);',
        '   d12 = dot(v2,v1);',
        '   float u = (d11 * d02 - d12 * d01) / (d00 * d11 - d01 * d01);',
        '   if (u < 0. || u > 1.)return 1.;',
        '   float v = (d12 * d00 - d01 * d02) / (d00 * d11 - d01 * d01);',
        '   if (v < 0. || v > 1.)return 1.;',
        '   return (u+v)-1.;',
        '}'
    ].join('\n'),
    drawSegment_vec2_p0_vec2_p1_vec2_uv_vec2_pos:[
        'float drawSegment(vec2 p0, vec2 p1,vec2 uv,vec2 pos)' ,
        '{' ,
        '   vec2 dir = normalize(p1 - p0);' ,
        '   vec2 cp = (uv - pos - p0) * mat2(dir.x, dir.y,-dir.y, dir.x);' ,
        '   return distance(cp, clamp(cp, vec2(0), vec2(distance(p0, p1), 0)));' ,
        '}' ,
    ].join('\n'),
};

export default ShaderMethod;

